home *** CD-ROM | disk | FTP | other *** search
- /*
- * MBMAIL.C - 10/03/92 The message file stuff, except for forwarding.
- */
-
- #include "mb.h"
- #ifdef MCH_AMIGA
- extern char optflags[];
- extern char tmpstr[];
- extern short all_number;
- extern short gotmail;
- extern short debug;
- short thebox = 0,kambbs = 0;
- extern short interflag;
- extern int srcmd_flag; /* for SR */
- struct lst_msg last_msg;
- #endif
-
- #define btmax 112 /* Max text in beacon line */
- #define ln_hier 64
-
- char orgmsg[6], orgbbs[7], orgtime[5], orgdate[7];
-
- char *mbfile, *mbbfile, *msgdir, *bidfile, *stfile;
- char bbidfile[] = "BID.TMP";
-
-
- char *ufwd; /* Calls with unread msgs, for BT */
- char *bfwd; /* Calls with unread msgs, for forwarding */
-
- short ufwdm, ufwdn, bfwdm, bfwdn, bidnum;
- short tstaleb, tstalen, tstaleu;
- short tstale1, tstale2, tstale3;
- short rstale1, rstale2, rstale3;
- int hasbid, needbid, holdit;
-
- char *mm[num_mm];
- char wpcall[ln_call];
- XBBS *xbbs;
- HOLD *hold;
-
- MAIL_HDR *mfhs;
- MSG_HDR *tmmhs;
-
- FILE *bfl;
-
- #ifndef MCH_AMIGA
- int mfl, mflb;
- #else
- int mfl = -1, mflb = -1;
- #endif
-
- msgfile(p, n)
- char *p;
- word n;
- {
- sprintf(p, "%s%u", msgdir, n);
- }
-
- /*
- * Open file to hold BIDs
- */
-
- opnbid()
- {
- #ifndef MCH_AMIGA
- if ((bfl = fopen(bidfile, "a+")) is NULL) { nofile(bidfile); exit(1); }
- #else
- /* This does not need locking since it only opens and closes the file */
- if((bfl = fopen(bidfile, "a+")) is NULL) {
- nofile(bidfile);
- done(1);
- }
- #endif
- fclose(bfl);
- }
-
- /*
- * Write message header.
- */
-
- wt_mmhs()
- {
- if (port->mmhs->rn) write_rec (mfl, port->mmhs->rn, (char *)port->mmhs);
- }
-
-
- /*
- * Get message title.
- */
-
- get_title()
- {
- while(!getdat());
- remnl(port->line);
- strncpy(port->mmhs->title, port->line, mhtitl);
- }
-
- /*
- * Parse the [@ bbs] and [< from] fields of a command.
- */
-
- atfrom(i)
- int i;
- {
- if (*port->fld[i] is '<') pcall(port->mmhs->from, port->fld[i + 1]);
- else if (*port->fld[i] is '@')
- {
- pcall(port->mmhs->bbs, port->fld[i +1]);
- if ((strchr(port->fld[i + 1], '.')) is NULL)
- { chkhier(); return; }
- port->mmhs->ext = 2;
- fill (port->mmhs->call, '\0', 124);
- strncpy(port->mmhs->call[0], port->fld[i + 1], ln_hier);
- }
- }
-
- /*
- * Parse the fields of a send command.
- */
-
- pfld()
- {
- #ifdef MCH_AMIGA
- short life = 0; /* ARF ARF! */
- short ltmp;
- /* for SR command. Any SR command with one or more arguments is
- an error
- */
- if(port->opt2 == 'R') {
- port->msg = mwhat;
- return(0);
- }
- #endif
- hasbid = false;
-
- port->mmhs->type = port->opt2;
- pcall(port->mmhs->to, port->fld[1]);
-
- /* If a message is to an individual and type is blank,
- * automatically make it a private message, else make it a bulletin.
- */
-
- if (port->opt2 is ' ')
- if (iscall(port->mmhs->to)) port->mmhs->type = 'P';
- else port->mmhs->type = 'B';
-
- strncpy(port->mmhs->from, port->user->call, ln_call);
- fill(port->mmhs->bbs, ' ', ln_call);
- fill(port->mmhs->bid, ' ', ln_bid);
- fill(port->mmhs->fwdc, '\0', ln_call);
- port->mmhs->ext = 0;
-
- #ifdef MCH_AMIGA
- /* Check the message type and do some fancy overriding where necessary */
- /* In particular there's a new fix here specifically for the KAM BBS in
- its V3.01 so that a personal message to an invalid callsign is forced
- to be a Bulletin
- */
- switch(port->mmhs->type) {
-
- case 'P':
- if(!kambbs)break;
- if(!iscall(port->mmhs->to)) {
- port->mmhs->type = 'B';
- }
- break;
- /* If type is blank then set it to Personal if the 'to' is a valid
- call, otherwise make it a bulletin
- */
- case ' ':
-
- if(iscall(port->mmhs->to)) {
- port->mmhs->type = 'P';
- }
- else {
- /* If the TO call is one letter long then someone is trying to send
- a THEBOX control message. Throw it away.
- */
- if((port->mmhs->to[1] == ' ') || (port->mmhs->to[1] == 0)) {
- outstr("No - I don't use control messages\n");
- needbid = 0;
- return(0);
- }
- port->mmhs->type = 'B';
- }
- break;
- /* THEBOX can send a 'S$' command. Set the type to Bulletin.
- THEBOX only accepts an 'S' command and ignores any option
- such as 'P', 'B' etc. If the message is TO a valid call
- then it is marked 'P'. If it is not 'P', it will mark it
- as 'B' if either there is no '@' field or if the '@' field
- is a valid call. If it is not 'B' but the FROM call is
- valid then it marks the message as '$'. If the TO field
- is only one character long then the message is marked 'C'.
- Failing all this the message is marked 'H' and is held.
- */
- case '$':
- port->mmhs->type = 'B';
- break;
- /* THEBOX can also send 'SC' which is some form of control message
- that doesn't mean anything to us. Reject it.
- */
- case 'C':
- outstr("No - I don't use control messages\n");
- needbid = 0;
- return(0);
- }
- /* The switch may have changed the type so we have to change the
- opt2 as well. They are almost the same thing.
- */
- port->opt2 = port->mmhs->type;
- /* Force Personal messages to require a BID .... for MID code */
- if(port->mmhs->type == 'P')needbid = 1;
-
- /* THEBOX can send us a message lifetime indicator at the end of an 'S'
- command. Save the number for later use but remove the field so the
- remaining code will see the bid at the end (if it is there).
- */
- life = -1;
- if(*port->fld[port->flds-1] is '#') {
- ltmp = atoi(&port->fld[port->flds-1][1]);
- if((ltmp > 0) && (ltmp < 256))life = ltmp;
- port->flds--;
- }
- /* If this is a bulletin and the lifetime isn't set then default it.
- */
- if((port->mmhs->type == 'B') && (life == -1))
- life = tstaleb;
- #endif
-
- if (port->flds > 3) atfrom(port->flds - 2);
- if (port->flds > 5) atfrom(port->flds - 4);
-
- #ifdef MCH_AMIGA
- /* routine added to mbuser to see if we have the user 'to' in our
- user record file. If so, then use our @bbs rather than the one
- in the message. We presume that if that user's name is on file
- here and we also have an @bbs for him, then it is likely to
- be just as accurate, or better, than the one in the message.
- In particular, this is useful for setting the @bbs field when
- a user leaves it out of an 'S' command.
- */
- replace_bbs();
-
-
- #endif
-
- if (port->flds > 2)
- if(*port->fld[port->flds-1] is '$')
- {
- /* MCH_AMIGA */
- if (*(port->fld[port->flds - 1] + 1)/* isnt NULL*/)
- {
- strncpy(port->mmhs->bid, port->fld[port->flds - 1] + 1, ln_bid);
- hasbid = true;
- }
- if (port->flds > 4) atfrom(port->flds - 3);
- if (port->flds > 6) atfrom(port->flds - 5);
- }
-
- initmsg(true);
-
- #ifdef MCH_AMIGA
- /* Store the message lifetime which will be set to the '#' field of
- a received message if it exists. Otherwise it will be the lifetime
- default for a bulletin or zero.
- */
- if(life)port->mmhs->lifetime = life;
-
- /* Check the reject.btn file to see if this message should be
- rejected.
- */
- if(test_reject()) {
- outstr("No - Rejected\n");
- needbid = 0;
- return(0);
- }
- /* Checks for unknown @BBS field and leaves it in tmpstr[0] if so */
- /* Must not use tmpstr between here and the warning message */
- ltmp = test_bbs();
- #endif
-
- if(!s_mart) {
- #ifdef MCH_AMIGA
- /* Part of the 'SR' command */
- if(last_msg.type)prt_subj();
- /* WATCH OUT .... I've bracketed this else across these two #ifdefs */
- else {
- if(ltmp) {
- outstr("WARNING: The @BBS field '");
- outstr(tmpstr);
- outstr("' is not known at this BBS\n");
- outstr(" Your message may not be delivered ... continue\n");
- }
-
- #endif
- if (port->user->options & (u_bbs | u_expert)) outstr("Sj:\n");
- else prtx(mm[0]);
- #ifdef MCH_AMIGA
- }
- /* Part of SR command - don't call get_title */
- if(last_msg.type == 0)
- #endif
- get_title();
- #ifndef MCH_AMIGA
- return;
- #else
- return(1);
- #endif
- }
- else {
- #ifdef MCH_AMIGA
- /* Check for unwanted bulletins.
- If this is a bulletin or it has a BID then see if we
- want this bulletin.
- If the @bbs has a corresponding
- msgs/bbs.dis then accept it, otherwise No tnx
- */
- if(optflags[0] && (port->mmhs->type == 'B')) {
- if(tmpstr[0] == 0) {
- outstr("No - Don't want it tnx\n");
- needbid = 0;
- return(0);
- }
- }
- #endif
- if (hasbid) {
- checkbid();
- if (!needbid) {
- outstr("NO\n");
- sprintf(port->mmhs->title, "<<%6.6s - %s>>",
- port->user->call, port->fld[port->flds-1]);
- wt_mmhs();
- #ifndef MCH_AMIGA
- return;
- #else
- return(0);
- #endif
- }
- prtx("OK\n");
- get_title();
- #ifndef MCH_AMIGA
- return;
- #else
- return(1);
- #endif
- }
- else {
- prtx("OK\n");
- get_title();
- needbid = true; /* will check and may assign one later */
- #ifndef MCH_AMIGA
- return;
- #else
- return(1);
- #endif
- }
- }
- #ifdef MCH_AMIGA
- /* Not sure it can get here ... but just in case */
- return(1);
- #endif
- }
-
- /*
- * Create the header line.
- */
-
- makehdr()
- {
- register char st,ef,ht;
- #ifdef MCH_AMIGA
- register char *p;
- #endif
-
- st = 'N';
- ht = ' ';
-
- #ifndef MCH_AMIGA
- if (port->mode & ops)
- {
- if (port->mmhs->stat & m_stale) st = 'O';
- if (port->mmhs->stat & m_bull) st = '$';
- if (port->mmhs->stat & m_hold)
- {
- st = 'H';
- if(port->mmhs->htype) ht = port->mmhs->htype;
- }
- }
- #endif
- if (port->mmhs->stat & m_fwd) st = 'F';
- if (port->mmhs->stat & m_read) st = 'Y';
- if (port->mmhs->stat & m_kill) st = 'K';
- if (port->mmhs->stat & m_busy) st = 'B';
- #ifdef MCH_AMIGA
- /* Show the sysop the true state of the messages. Doing this first means
- all the other states e.g. 'Y' override these
- */
- if (port->mode & ops)
- {
- if (port->mmhs->stat & m_stale) st = 'O';
- if (port->mmhs->stat & m_bull) st = '$';
- if (port->mmhs->stat & m_hold) st = 'H';
- }
- #endif
- if (port->mmhs->ext is 2) ef = '*'; else ef = ' ';
- #ifndef MCH_AMIGA
- sprintf(tmp->scr,"%5u %c%c%c%5u %6.6s %6.6s %6.6s%c%3u %4.4s/%4.4s %s\n",
- port->mmhs->number, port->mmhs->type, st, ht, port->mmhs->size,
- port->mmhs->to,port->mmhs->from,port->mmhs->bbs,ef,port->mmhs->read,
- port->mmhs->date + 2, port->mmhs->time, port->mmhs->title);
- #else
- /* Don't let the title exceed the line length */
- sprintf(tmpstr,"%-27.27s",port->mmhs->title);
- for(p=tmpstr;*p;p++);
- p--;
- while((p > tmpstr) && (*p == ' '))p--;
- p++;
- *p = 0;
- sprintf(tmp->scr,"%5u %c%c%c%5u %6.6s %6.6s %6.6s%c%3u %4.4s/%4.4s %s\n",
- port->mmhs->number, port->mmhs->type, st, ht, port->mmhs->size,
- port->mmhs->to,port->mmhs->from,port->mmhs->bbs,ef,port->mmhs->read,
- port->mmhs->date + 2, port->mmhs->time, tmpstr);
- #endif
-
- if ((port->opt2 is 'K') and (port->mode & ops))
- {
- if (!port->mmhs->fport) port->mmhs->fport = ' ';
- sprintf(tmp->scr+37, ">%6.6s %c->%6.6s %s\n",port->mmhs->fwdd,
- port->mmhs->fport, port->mmhs->fwdc, port->mmhs->title);
- }
- }
-
- /*
- * Write mail.dat header into text file
- */
-
- makehdr2()
- {
- register char st, c;
- int msfl;
- char flags[mmesn];
- fill (flags, ' ',mmesn);
- fill (tmp->scr, '\0', 256);
- tmp->scr[254] = '\r'; tmp->scr[255] = '\n';
- #ifdef MCH_AMIGA
- /* Save the lifetime in the header so that mbrestm can recover it */
- tmp->scr[252] = port->mmhs->lifetime;
- #endif
- if (port->mmhs->ext is 1)
- {
- for (c=0; c < port->mmhs->count; c++)
- flags[c] = port->mmhs->flag[c] + '0';
- }
- st = 'N';
- if (port->mmhs->stat & m_busy) st = 'B';
- if (port->mmhs->stat & m_stale) st = 'O';
- if (port->mmhs->stat & m_fwd) st = 'F';
- if (port->mmhs->stat & m_bull) st = '$';
- if (port->mmhs->stat & m_hold) st = 'H';
- if (port->mmhs->stat & m_read) st = 'Y';
- if (port->mmhs->stat & m_kill) st = 'K';
- sprintf(tmp->scr,
- "%5u %c%c %5u %6.6s %6.6s %6.6s %6.6s %4.4s %-12.12s %5u\r\n",
- port->mmhs->number, port->mmhs->type, st, port->mmhs->size,
- port->mmhs->to, port->mmhs->from, port->mmhs->bbs,
- port->mmhs->date, port->mmhs->time, port->mmhs->bid, port->mmhs->read);
- if (port->mmhs->ext is 2)
- sprintf(tmp->scr+68, "%c %s\r\n%s\r\n", port->mmhs->ext +'0',
- port->mmhs->call, port->mmhs->title);
- else sprintf(tmp->scr+68, "%c %13.13s \r\n%s\r\n", port->mmhs->ext +'0',
- flags, port->mmhs->title);
-
- msgfile(port->cmd, port->mmhs->number);
- if ((msfl = open(port->cmd, O_WRONLY | O_BINARY)) < 0) return;
- write_rec(msfl, 0, (char *)tmp->scr);
- close(msfl);
- }
-
- /*
- * Print a message header.
- */
-
- char prthdr(tit, max_title)
- int tit, max_title;
- {
- char *a, *b;
-
- register short i;
- register short docc;
-
- #ifndef MCH_AMIGA
- if (tit) prtx(mm[3]);
- #else
- /* If we print a title then start the line counter as well. */
- if (tit) {
- prtx(mm[3]);
- pgst(NULL);
- pgck();
- }
- #endif
- makehdr();
- if (strlen(tmp->scr) > 79)
- {
- if (!max_title)
- {
- tmp->scr[79] = '\n';
- tmp->scr[80] = '\0';
- }
- else if (lstquit()) return ('Q');
- }
- outstr(tmp->scr);
- if (lstquit()) return ('Q');
- if((port->opt1 is 'L') and
- ((*port->fld[1] isnt ';') and
- (*port->fld[2] isnt ';') and (*port->fld[3] isnt ';')))
- return(' ');
- if(*port->mmhs->fwdc) if (port->mode & ops)
- {
- sprintf(port->line,
- " <<%6.6s F->%6.6s", port->mmhs->fwdd, port->mmhs->fwdc);
- outstr(port->line);
- if (!(port->mmhs->ext))
- {
- outchar('\n');
- if (lstquit()) return ('Q');
- }
- }
- if (port->mmhs->ext is 2)
- {
- outstr(" EF:");
- outstr(port->mmhs->call[0]);
- outchar('\n');
- if (lstquit()) return ('Q');
- }
- if (port->mmhs->ext is 1) if (port->mode & ops)
- {
- docc = false;
- for (i = 0; i < port->mmhs->count; i++) if (port->mmhs->flag[i])
- docc = true;
-
- if (docc)
- {
- outstr(" cc:");
- for (i = 0; i < port->mmhs->count; i++)
- {
- if (port->mmhs->flag[i]) outchar(' '); else outstr(" *");
- outnb(port->mmhs->call[i], ln_call);
- }
- outchar('\n');
- if (lstquit()) return ('Q');
- }
- }
- if (port->mode & ops) if (*port->mmhs->bid isnt ' ')
- {
- outstr(" BID: ");
- a = port->line;
- b = port->mmhs->bid;
- unbl(a, b, ln_bid);
- outstr(port->line); outchar('\n');
- if (lstquit()) return ('Q');
- }
- #ifdef MCH_AMIGA
- if((port->mode & ops) && (port->mmhs->type == 'B')) {
- sprintf(tmpstr," Life: %u\n",port->mmhs->lifetime);
- outstr(tmpstr);
- if(lstquit())return('Q');
- }
- #endif
- return(' ');
- }
-
- lstquit()
- {
- if ((pgck() is 'Q') or (chkdis())) return true;
- return false;
- }
-
- /*
- * Read the message, look for the last bbs header.
- * Set the @ field of the current message to the "at bbs" in that header.
- */
-
- findat()
- {
- register short i;
-
- fill(port->mmhs->bbs, ' ', ln_call);
- msgfile(port->line, port->mmhs->number);
- if ((port->fl = fopen(port->line, "r")) is NULL) { nofile(port->line); return; }
- fseek(port->fl, (long)RECSIZE, 0);
- while(fgets(port->line, linelen, port->fl) isnt NULL)
- {
- if (!parsehd(port->line)) break;
- pcall(port->mmhs->bbs, orgbbs);
- }
- fclose (port->fl);
- chkhier();
- }
-
- /*
- * Parse a message header line.
- */
-
- parsehd(in)
- char *in;
- {
- register char *p;
- register int count, n;
-
- if (!ishead(in)) return false;
-
- p = strchr(in, 'R');
- p++;
-
- if (*p is ':') p++;
- if (*p is ' ') p++;
- count = 6;
- n = 0;
- while (*p and count--)
- {
- if (!isdigit(*p)) break;
- orgdate[n++] = *p++;
- }
- orgdate[n] = '\0';
-
- if (*p is '/') p++;
-
- count = 4;
- n = 0;
- while (*p and count--)
- {
- if (!isdigit(*p)) break;
- orgtime[n++] = *p++;
- }
- orgtime[n] = '\0';
-
-
- if ((p = strchr(in, '@')) is NULL) return false;
- {
- p++;
-
- /* skip colon or a space in @:call OR @ call */
-
- while ((*p is ':')or(*p is ' ')) p++;
- count = ln_call;
- n = 0;
- while (*p and count--)
- {
- if (!isalnum(*p)) break;
- toupper(*p);
- orgbbs[n++] = *p++;
- }
- orgbbs[n] = '\0';
- }
-
- if (((p = strrchr(in, '#')) isnt NULL) and (*(p+1) is ':'))
- {
- p++;
-
- while ((*p is ':')or(*p is ' ')) p++;
- count = 5;
- n = 0;
- while (*p and count--)
- {
- if (!isalnum(*p)) break;
- orgmsg[n++] = *p++;
- }
- orgmsg[n] = '\0';
- }
- else
- {
- p = strchr(in, '@');
- p--; count = 5;
- while(count-- and *p isnt ' ') p--;
- p++;
- if (*p is '<') p++;
- count = 5;
- n = 0;
- while (*p and count--)
- {
- if (*p is '@') break;
- orgmsg[n++] = *p++;
- }
- orgmsg[n] = '\0';
- }
- return true;
- }
-
-
- /*
- * Find a message given it's number.
- */
-
- findmsg(nr)
- word nr;
- {
- register word i;
-
- #ifdef MCH_AMIGA
- check_mail();
- unlock_mail();
- #endif
- for (i = mfhs->last; i; i--)
- {
- read_rec(mfl, i, (char *)port->mmhs);
- if (port->mmhs->number is nr) return true;
- }
- return false;
- }
-
- /*
- * Create the distribution list, if required.
- */
-
- dodis()
- {
- register FILE *dfl;
- #ifndef MCH_AMIGA
- if (port->mmhs->ext is 2) return;
- port->mmhs->ext = 0;
- #else
- /* The code has been modified so that if ->ext is non-zero then dodis()
- has already been called ( == 1) or doesn't need to be called ( == 2).
- */
- if (port->mmhs->ext) return;
- #endif
- if (*port->mmhs->bbs is ' ') return;
-
- unbl(tmp->scr, port->mmhs->bbs, ln_call);
-
- strcpy(port->line, msgdir);
- strcat(port->line, tmp->scr);
- strcat(port->line, ".DIS");
-
- if ((dfl = fopen(port->line, "r")) is NULL) return;
-
- port->mmhs->ext = 1 ;
-
- for (port->mmhs->count = 0;
- (port->mmhs->count < mmesn) and (fgets(tmp->scr, scrmax, dfl) isnt NULL);
- port->mmhs->count++)
- {
- strupr(tmp->scr);
- pcall(port->mmhs->call[port->mmhs->count], tmp->scr);
- #ifdef MCH_AMIGA
- /* Blank lines are bad news! */
- if(port->mmhs->call[port->mmhs->count][0] == ' ') {
- port->mmhs->count--;
- continue;
- }
- #endif
- if(matchn(port->mmhs->call[port->mmhs->count], port->user->call, ln_call))
- port->mmhs->flag[port->mmhs->count] = false;
- else port->mmhs->flag[port->mmhs->count] = true;
- }
- fclose(dfl);
- }
-
- /*
- * Do we hold this message?
- */
-
- ishold(c)
- char *c;
- {
- register HOLD *hp;
-
- for (hp = hold; hp isnt NULL; hp = hp->next)
- if (matchn(hp->call, c, ln_call)) return true;
-
- return false;
- }
-
- /*
- * Create message utilities - initmsg and cremsg.
- * Used by "send message", "make message from file",
- * "kill msg" (service messages), "copy message".
- */
-
- initmsg(h)
- int h;
- {
- if (s_flag & s_dv) begin_lock();
- #ifdef MCH_AMIGA
- check_mail();
- #else
- read_rec(mfl, 0, (char *)mfhs);
- #endif
-
- port->mmhs->rn = mfhs->next++;
- port->mmhs->number = mfhs->next_msg++;
- #ifdef MCH_AMIGA
- set_mail((long)mfhs->next);
- #endif
- port->mmhs->stat = m_busy;
- #ifndef MCH_AMIGA
- strncpy(port->mmhs->date, l_date, ln_date);
- strncpy(port->mmhs->time, l_time, ln_time);
- #else
- /* Use UTC for the file creation date. */
- strncpy(port->mmhs->date, z_date, ln_date);
- strncpy(port->mmhs->time, z_time, ln_time);
- #endif
- port->mmhs->read = 0;
- port->mmhs->size = 0;
- if(port->mmhs->ext isnt 2) fill(port->mmhs->call, '\0', 124);
- if(h)sprintf(port->mmhs->title, "<<%6.6s -- disconnected>>",port->user->call);
- pcall(port->mmhs->fwdd, port->user->call, ln_call);
-
- #ifdef MCH_AMIGA
- port->mmhs->lifetime = 0;
- #endif
- /*
- * Clean up the file header.
- */
-
- if (!mfhs->first) mfhs->first = port->mmhs->rn;
- mfhs->last = port->mmhs->rn;
- mfhs->count++;
- write_rec(mfl, 0, (char *)mfhs);
- wt_mmhs();
- mfhs->next_msg--;
- if (s_flag & s_dv) end_lock();
- #ifdef MCH_AMIGA
- unlock_mail();
- titles();
- #endif
- }
-
- cremsg()
- {
- register XBBS *xp;
-
- port->mmhs->stat = 0;
- #ifndef MCH_AMIGA
- strncpy(port->mmhs->date, l_date, ln_date);
- strncpy(port->mmhs->time, l_time, ln_time);
- #else
- /* Use UTC for the file creation date. */
- strncpy(port->mmhs->date, z_date, ln_date);
- strncpy(port->mmhs->time, z_time, ln_time);
- #endif
- port->mmhs->read = 0;
- port->mmhs->size = filesize;
-
- for (xp = xbbs; xp isnt NULL; xp = xp->next)
- if (wcm(xp->from, port->mmhs->bbs))
- {
- strncpy(port->mmhs->bbs, xp->to, ln_call);
- if (port->mmhs->ext is 2) port->mmhs->ext = 0;
- if (wcm(xp->from, xp->to)) port->mmhs->stat setbit m_bull;
- break;
- }
-
- if (ishold(port->mmhs->to))
- {
- port->mmhs->stat = m_hold;
- port->mmhs->htype = 'T';
- }
- if (ishold(port->mmhs->from))
- {
- port->mmhs->stat = m_hold;
- port->mmhs->htype = 'F';
- }
- if (ishold(port->mmhs->bbs))
- {
- port->mmhs->stat = m_hold;
- port->mmhs->htype = 'B';
- }
-
- if (ishold("HUSER "))
- {
- if (!(port->user->options & (u_sysop|u_bbs)))
- if (port->mmhs->type is 'B')
- {
- port->mmhs->stat = m_hold;
- port->mmhs->htype = 'H';
- }
- }
-
- if (holdit) port->mmhs->stat = m_hold;
-
- if (*port->mmhs->bid isnt ' ')
- {
- checkbid();
- if (hasbid) if (!holdit) if (needbid) putbid(true);
- }
- dodis();
-
- if ((port->mmhs->ext is 1) and (*port->mmhs->bid is ' '))
- {
- port->mmhs->stat = m_hold;
- port->mmhs->htype = 'N';
- }
-
- #ifdef MCH_AMIGA
- /* If there's only one call in the distribution list and that's who the
- bulletin was received from, then mark the bulletin as forwarded
- */
- if((port->mmhs->ext == 1) && (port->mmhs->count == 1)) {
- if(port->mmhs->flag[0] == false)
- port->mmhs->stat = m_fwd;
- }
- #endif
-
- wt_mmhs();
- makehdr2();
-
- if (*port->fld[port->flds-1] isnt '$') port->fld[port->flds-1] = nullstr;
-
- sprintf(port->line, "%u %-.6s@%-.6s %s %s", port->mmhs->number,
- port->mmhs->to, port->mmhs->bbs, port->fld[port->flds-1], port->mmhs->title);
-
- log('M', port->opt1, port->opt2, port->line);
- mfhs->next_msg++;
- #ifdef MCH_AMIGA
- titles();
- #endif
- }
-
- /*
- * Set up the beacon line.
- */
-
- setfwd()
- {
- register char *cp, *lp;
- register short i;
-
- #ifdef MCH_AMIGA
- all_number = 0;
- gotmail = 0;
- #endif
-
- bldfwd();
- #ifndef MCH_AMIGA
- if (ufwdm > 1)
- {
- strcpy(port->line, "BT Mail for:");
- cp = ufwd;
- lp = port->line + strlen(port->line);
- #else
- /* ufwdm > 1 is a bug. ufwdm is the MAX # of permitted callsigns.
- It should be ufwdn > 0 which checks for actual number of callsigns.
- I have also moved the strcpy and the alltnc() outside the 'if'
- so that the beacon text is changed if there is no mail. The problem
- that can occur is that if there is currently one call in the btext
- and then that mail is read, then there is now no call in the btext
- but the original code doesn't change the BText to a null.
- */
- strcpy(port->line, "BT Mail for:");
- cp = ufwd;
- lp = port->line + strlen(port->line);
- if(ufwdn > 0) {
- /* Does sysop have mail? */
- for(i=0;i<ufwdn;i++) {
- if(matchn(&ufwd[i*ln_call],cport->user->call,ln_call)) {
- gotmail++;
- break;
- }
- }
- #endif
- while ((cp < ufwd + ln_call * ufwdn) and (lp < port->line + btmax))
- {
- *lp++ = ' ';
- for (i = 0; i < ln_call; i++, cp++) if (*cp isnt ' ') *lp++ = *cp;
- }
- #ifndef MCH_AMIGA
- *lp++ = '\n';
- *lp = '\0';
- alltnc(port->line);
- }
- #else
- }
- if(lp < port->line + btmax) {
- /* If there's room, add ALL(N) on the end */
- if(all_number) {
- sprintf(tmpstr," ALL(%d)",all_number);
- strcpy(lp,tmpstr);
- lp += strlen(tmpstr);
- }
- }
- /* store LF at the end of the beacon command */
- *lp++ = '\n';
- *lp = '\0';
- alltnc(port->line);
- /* setfwd may find that sysop has mail so call titles just in case */
- titles();
- #endif
- }
-
- /*
- * General permission check: sysop or TO or FROM.
- */
-
- permit()
- {
- if (port->mmhs->stat & (m_kill | m_busy)) return false;
- if (matchn(port->user->call, port->mmhs->to, ln_call) and
- !(port->mmhs->stat & m_hold)) return true;
- if (matchn(port->user->call, port->mmhs->from, ln_call)) return true;
- return false;
- }
-
- /*
- * Return true if user has kill permission for current message.
- */
-
- kpermit()
- {
- if (port->mmhs->stat & m_kill) return false;
- if (port->mode & ops) return true;
- if (permit()) return true;
- return ((port->mmhs->type is 'T') and (port->opt2 is 'T'));
- }
-
- /*
- * Return true if user has list permission for current message.
- */
-
- lpermit()
- {
- if (port->user->options & u_sysop) return true;
- if (permit()) return true;
- #ifdef MCH_AMIGA
- /* Users should be able to list a bulletin that has been forwarded.
- I did it this way, rather than remove the m_fwd from the final
- return statement, to avoid any unknown side-effects
- */
- if((port->mmhs->type == 'B') && (port->mmhs->stat & m_fwd))return(true);
- #endif
- return ((port->mmhs->type isnt 'P')
- and !(port->mmhs->stat & (m_fwd | m_kill | m_busy | m_hold)));
- }
-
- /*
- * Return true if user has read permission for current message.
- */
-
- rpermit()
- {
- if ( port->mode & ops) return true;
- if (permit()) return true;
- return (port->mmhs->type isnt 'P');
- }
-
- /*
- * Clean the mail file.
- * Force drain of buffers, update of directory item.
- */
-
- clnmsg()
- {
- #ifdef MCH_AMIGA
- lock_mail();
- #endif
- close(mfl);
- mfl = open(mbfile, O_RDWR | O_BINARY);
- #ifdef MCH_AMIGA
- unlock_mail();
- #endif
- }
-
- /*
- * Close the mail file.
- */
-
- clsmsg()
- {
- #ifdef MCH_AMIGA
- if(mfl >= 0)
- #endif
- close (mfl);
- }
-
- /*
- * Open the mail file.
- */
-
- opnmsg()
- {
- register char *tp;
-
- /*
- * Allocate space for the mail file records.
- */
-
- mfhs = (MAIL_HDR *) malloc(sizeof(MAIL_HDR));
- tmmhs = (MSG_HDR *) malloc(sizeof(MSG_HDR));
-
- /*
- * Allocate the "who has mail" lists.
- */
-
- ufwd = (char *) malloc (ln_call * ufwdm);
- bfwd = (char *) malloc (ln_call * bfwdm);
- #ifndef MCH_AMIGA
- if (bfwd is NULL) errall();
- #else
- if (bfwd is NULL) errall(1);
- #endif
-
- /*
- * Open the file. If it does not exist, make one.
- */
-
- #ifdef MCH_AMIGA
- lock_mail();
- #endif
- if ((mfl = open(mbfile, O_RDWR | O_BINARY)) < 0)
- {
- if ((mfl = open(mbfile, O_CREAT | O_RDWR | O_BINARY, pmode)) < 0)
- #ifndef MCH_AMIGA
- { nofile(mbfile); exit(1); }
- #else
- {
- nofile(mbfile);
- #ifdef MCH_AMIGA
- unlock_mail();
- #endif
- done(1);
- }
- #endif
- inithdr();
- mfhs->next_msg = 1;
- #ifdef MCH_AMIGA
- titles();
- #endif
- write_rec(mfl, 0, (char *)mfhs);
- }
-
- /*
- * Read the mail file header.
- */
-
- read_rec(mfl, 0, (char *)mfhs);
-
- #ifdef MCH_AMIGA
- unlock_mail();
- #endif
- /*
- * If wrong version mail file, quit now.
- */
-
- if (mfhs->version isnt mb_version)
- {
- #ifndef MCH_AMIGA
- printf("Expected version %d, got version %d\n",
- mb_version, mfhs->version);
- #else
- sprintf(tmpstr,"Expected version %d, got version %d\n",
- mb_version, mfhs->version);
- ttputs(tmpstr);
- #endif
- nofile(mbfile);
- #ifndef MCH_AMIGA
- exit(1);
- #else
- done(1);
- #endif
- }
-
- }
-
- /*
- * Initialize the mail file header.
- */
-
- inithdr()
- {
- #ifdef MCH_AMIGA
- set_mail(1L);
- #endif
- mfhs->next = 1;
- mfhs->first = 0;
- mfhs->last = 0;
- mfhs->version = mb_version;
- mfhs->free = 0;
- mfhs->count = 0;
- mfhs->unt_msg = 1;
-
- #ifdef MCH_AMIGA
- titles();
- #endif
- curtim();
- strncpy(mfhs->date, l_date, ln_date);
- strncpy(mfhs->time, l_time, ln_time);
- fill(mfhs->unu, '\0', mfhsunu);
- }
-
- /*
- * Open mail file and read first record.
- */
-
- readmsg()
- {
- #ifdef MCH_AMIGA
- lock_mail();
- #endif
- mfl = open(mbfile, O_RDWR | O_BINARY);
- read_rec(mfl, 0, (char *)mfhs);
- #ifdef MCH_AMIGA
- unlock_mail();
- #endif
- }
-
- /*
- * Does this station want us to send BIDs ?
- */
-
- isbid()
- {
- register char *f;
-
- /* Is this a sid? It must have a '-' and end with a ']' */
-
- if ((port->line[strlen(port->line) - 2] isnt ']' ) or
- ((f = strrchr(port->line, '-')) is NULL))
- return;
-
- #ifdef MCH_AMIGA
- /* Look for THEBOX */
- if(matchn(&port->line[1],"THEBOX",6) ||
- matchn(&port->line[1],"DL5UY",5))
- thebox = 1;
- /* Look for the newer KAM BBS which can handle BBS mail */
- /* The KAM wouldn't need to be specifically recognized except that
- it only allows sending personal messages. So if someone sends
- a personal meesage to ALL @ ALLCAN it ought to be a bulletin.
- The program will change such personal messages to bulletins.
- */
- if(matchn(&port->line[1],"KAM",3)) kambbs = 1;
- #endif
- /* Look for special characters in the last field. */
-
- f++;
- for (; *f isnt ']';f++)
- switch(*f)
- {
- case 'H' : s_mart setbit hidok; break;
- case '$' : s_mart setbit bidok; break;
-
- #ifdef MCH_AMIGA
- case 'F' : s_mart setbit fbbok; break;
- case 'B' : s_mart setbit cmpok; break;
- case 'M' : s_mart setbit midok; break;
- #ifdef MCH_ZOO
- /* I was trying to get C-BBS to use the zoo compression routines instead of
- the lzhuf from FBB. But with no success so far.
- */
- case 'Z' : s_mart setbit zoook; break;
- #endif
- #endif
-
-
- }
- #ifdef MCH_AMIGA
- /* If both B and Z are set then Z overrides (Z is better) */
- if((s_mart & (cmpok|zoook)) == (cmpok|zoook)) {
- s_mart clrbit cmpok;
- }
-
- /* If FBB compression bit is set but FBB itself is not, then clear the
- compression
- If option #C is selected force the compression off anyway.
- */
- if((s_mart & (fbbok|cmpok)) == cmpok)s_mart clrbit cmpok;
- if(!optflags[2])s_mart clrbit cmpok;
-
- #endif
-
- }
-
- /*
- * Check to see whether we already have this BID.
- */
-
- checkbid()
- {
- FILE *out;
- char *a, *b;
-
- if(*port->mmhs->bid is ' ') {
- needbid = true;
- return;
- }
- #ifdef MCH_AMIGA
- lock_bid();
- #endif
- if((out = fopen(bidfile, "r")) is NULL) {
- #ifdef MCH_AMIGA
- unlock_bid();
- #endif
- nofile(bidfile); return;
- }
- while(fgets(port->line, linelen, out) isnt NULL) {
-
- /* the first 4 characters are the date */
-
- strcpy(port->cmd, port->line + 4);
- a = port->cmd;
- remnl(a);
-
- a = port->line;
- b = port->mmhs->bid;
- unbl(a, b, ln_bid);
-
- if(match(port->cmd, port->line)) {
- needbid = false;
- fclose(out);
- #ifdef MCH_AMIGA
- unlock_bid();
- #endif
- return;
- }
- }
- needbid = true;
- fclose(out);
- #ifdef MCH_AMIGA
- unlock_bid();
- #endif
- }
-
- putbid(y)
- int y;
- {
- FILE *out;
- char *a, *b;
-
- #ifdef MCH_AMIGA
- lock_bid();
- #endif
- if ((out = fopen(bidfile, "a")) is NULL)
- {
- #ifdef MCH_AMIGA
- unlock_bid();
- #endif
- port->msg = mcant; return;
- }
- a = port->cmd;
- if (y) b = port->mmhs->bid; else b = tmp->scr;
- unbl( a, b, ln_bid);
- sprintf (port->line, "%4.4s%s\n", port->mmhs->date+2, port->cmd);
- if (s_flag & s_dv) begin_lock();
- fputs(port->line, out);
- if (s_flag & s_dv) end_lock();
- fclose(out);
- #ifdef MCH_AMIGA
- unlock_bid();
- #endif
- }
-
-
- /****************************************
- * *
- * Code for the commands starts here *
- * *
- ****************************************/
-
- /*
- * GM or GR command: backup the mail file.
- */
-
- untmsg()
- {
- register word inhdr, me;
- if (port->opt2 isnt 'A') { if (sure()) return false; }
- if (!mfhs->count) { port->msg = mm[5]; return false; }
- prtx(mm[6]);
-
- close(mfl); /* Close current. */
-
- unlink(mbbfile); /* Delete backup */
-
- /*
- * Copy current to backup.
- */
-
- if (samedir(mbfile, mbbfile)) rename(mbfile, mbbfile);
- else copy(mbfile, mbbfile, false);
-
- unlink(mbfile); /* Delete current. */
-
- /*
- * Open new current and backup.
- */
-
- mfl = open(mbfile, O_CREAT | O_RDWR | O_BINARY, pmode);
- mflb = open(mbbfile, O_RDONLY | O_BINARY);
-
- read_rec(mflb, 0, (char *)mfhs);
- me = mfhs->last;
- inhdr = mfhs->first;
- inithdr();
-
- if (port->opt2 is 'R')
- {
- if (port->flds is 1) mfhs->next_msg = 1;
- else mfhs->next_msg = atoi(port->fld[1]);
- }
-
-
- while(inhdr <= me) /* For each message header ... */
- {
- read_rec(mflb, inhdr, (char *)port->mmhs); /* Read the header. */
-
- /*
- * Tell the sysop about this message.
- */
-
- sprintf(port->line, "%c %6u Size %6u # %6u Read %6u", port->mmhs->type,
- inhdr, port->mmhs->size, port->mmhs->number, port->mmhs->read);
- outstr(port->line);
-
- inhdr++;
-
- if (!(port->mmhs->stat & ( m_kill | m_busy)))
- {
- outstr("\n");
-
- /*
- * If renumbering messages, renumber this message.
- */
-
- if (port->opt2 is 'R')
- {
- msgfile(port->line, port->mmhs->number);
- msgfile(port->cmd, mfhs->next_msg);
- rename(port->line, port->cmd);
- port->mmhs->number = mfhs->next_msg++;
- }
-
- /*
- * Write the header.
- */
-
- port->mmhs->rn = ++mfhs->count;
- wt_mmhs();
- }
- else arcmsg();
- }
-
-
- /*
- * Write the file header.
- */
- if (mfhs->count) mfhs->first = 1;
- mfhs->next = mfhs->count + 1;
- #ifdef MCH_AMIGA
- set_mail((long)mfhs->next);
- #endif
- mfhs->last = mfhs->count;
- mfhs->unt_msg = mfhs->next_msg;
- write_rec(mfl, 0, (char *)mfhs);
- close(mflb);
- clnmsg();
- #ifdef MCH_AMIGA
- titles();
- #endif
- return(true);
- }
-
-
- /*
- * Print headers of unread messages for this user.
- */
-
- newmsg()
- {
- if (findfwd(port->user->call, ufwd, ufwdn) or
- findfwd(port->user->call, bfwd, bfwdn))
- {
- prtx(mm[2]);
- port->opt2 = '\0';
- port->flds = 1;
- lstmsg();
- }
- }
-
- /*
- * L command, list messages.
- */
-
- lstmsg()
- {
- register short done, ok;
- word h, found, more, start;
- int max_title;
- #ifdef MCH_AMIGA
- int quote;
- quote = 0;
- interflag = 0;
- #endif
-
- if(port->mode & ops) max_title = false;
- else max_title = true;
-
- /*
- * First set up arguments.
- */
-
- found = 0; more = 0; done = false;
- #ifndef MCH_AMIGA
- if ((*port->fld[1] is ';')or(*port->fld[2] is ';')or(*port->fld[3] is ';'))
- #else
- /* The ';' must be the last thing on the line if it is there.
- The previous argument can be a quoted string to do a search of
- the title of those articles that otherwise qualify.
- */
- if(*port->fld[port->flds-1] is ';')
- #endif
- { port->flds--; max_title = true; }
-
- #ifdef MCH_AMIGA
- /* If the last argument is a quoted string, remember where it is but
- pretend to remove it
- */
- if(*port->fld[port->flds-1] is '"') {
- quote = --port->flds;
- }
- #endif
-
- switch(port->opt2)
- {
- case '@' :
- case '<' :
- case '>' : pcall(tcall, port->fld[1]); break;
- case 'S' : if (port->flds is 1) {port->msg = mwhat; return;}
- case '\0': break;
- case 'E' :
- case ' ' : if (port->flds is 1) more = port->user->msg_number;
- default :
- if (port->flds > 1)
- {
- if (!num(port->fld[1])) { port->msg = mwhat; return; }
- more = atoi(port->fld[1]);
- }
- if (port->flds is 3)
- {
- if (!num(port->fld[2])) { port->msg = mwhat; return; }
- start = atoi(port->fld[2]);
- }
- }
-
- /*
- * Log it, unless is initial login check for msgs.
- */
-
- if (port->opt2)
- {
- sprintf(port->line, "%u", more);
- log('M', 'L', port->opt2, port->line);
- }
-
- /*
- * Paw through the messages and show what requested.
- */
-
- #ifdef MCH_AMIGA
- check_mail();
- unlock_mail();
- #endif
- for (h = mfhs->last; h and !done; h--)
- {
- read_rec(mfl, h, (char *)port->mmhs);
- if ((port->opt2 is 'L') or ((port->opt2 is 'E') and (port->flds is 2)))
- done = (found is more); else done = (port->mmhs->number < more);
-
- ok = !done;
- if (port->flds is 3) if (ok)
- ok = (port->mmhs->number <= start);
- /*
- * Does this user have read permission for this message?
- */
-
- if (ok) ok = lpermit();
- if (ok) if (port->mmhs->stat & m_kill)
- ok=((port->opt2 is 'K')or(port->opt2 is 'E')or(port->opt2 is 'S'));
- if (ok) if (port->mmhs->stat & m_busy) ok = (port->opt2 is 'E');
-
- /*
- * Is this message wanted?
- */
-
- if (ok) switch(port->opt2)
- {
- case '\0': ok = matchn(port->user->call, port->mmhs->to, ln_call); break;
- case 'E' : break;
- case 'K' : ok = (port->mmhs->stat & m_kill); break;
- case 'F' : ok = (port->mmhs->stat & m_fwd); break;
- case 'H' : ok = (port->mmhs->stat & m_hold); break;
- case 'L' : break;
- case 'M' : ok = matchn(port->user->call, port->mmhs->to, ln_call);
- if (!ok) ok = matchn(port->user->call, port->mmhs->from, ln_call);
- break;
-
- case 'O' : ok = (port->mmhs->stat & m_stale); break;
- #ifdef MCH_AMIGA
- /* Fix up strlen in 2 calls to search() .*/
- #endif
- case 'S' : ok = (search(strupr(port->mmhs->title), port->fld[1],
- (short)strlen(port->fld[1]))or search(port->mmhs->to,
- port->fld[1],(short) strlen(port->fld[1]))); break;
- case 'U' : ok = !((port->mmhs->type is 'B')or(port->mmhs->type is 'A')
- or (port->mmhs->stat & (m_fwd | m_read))); break;
- case 'Y' : ok = (port->mmhs->stat & m_read); break;
- #ifndef MCH_AMIGA
- case '@' : ok = matchn(tcall, port->mmhs->bbs, ln_call); break;
- case '<' : ok = matchn(tcall, port->mmhs->from, ln_call); break;
- case '>' : ok = matchn(tcall, port->mmhs->to, ln_call); break;
- #else
- /* Permit a wildcard in these three forms of the 'L' command */
- /* wmatch is in dir.c */
- case '@' : ok = wmatch(port->mmhs->bbs ,tcall); break;
- case '<' : ok = wmatch(port->mmhs->from,tcall); break;
- case '>' : ok = wmatch(port->mmhs->to ,tcall); break;
- #endif
- default : ok = ((port->mmhs->type is port->opt2) or
- (port->opt2 is ' '));
- }
- #ifdef MCH_AMIGA
- if(ok && quote) {
- /*
- If there was a quoted string in the argument list,
- check to see if it occurs in the title. If not,
- then ignore it. (umatch is in dir.c)
- */
- if(!umatch(&port->mmhs->title[0],port->fld[quote]))ok = 0;
- }
- if(interflag && (port != cport)) {
- return;
- }
- #endif
- if (ok) if (prthdr(!found++, max_title) is 'Q') return;
- }
- if (!found) port->msg = mfind;
- s_flag setbit s_update;
- }
-
- /*
- * CM command: duplicate a message.
- */
-
- dupmsg()
- {
- word tmpsize;
- if (!findmsg(atoi(port->fld[2]))) { port->msg = mnmsg; return; }
- port->opt1 = 'S';
-
- prthdr(true, true);
- pcall(port->mmhs->to, port->fld[1]);
- fill(port->mmhs->bbs, ' ', ln_call);
- port->mmhs->ext = 0;
-
- if (port->flds > 3) atfrom(port->flds - 2);
- if (port->flds > 5) atfrom(port->flds - 4);
- tmpsize = port->mmhs->size;
-
- #ifdef MCH_AMIGA
- /* Override @bbs if the user is on file */
- replace_bbs();
- #endif
-
- msgfile(port->cmd, port->mmhs->number);
- initmsg(false);
- msgfile(port->line, mfhs->next_msg);
- copy(port->cmd, port->line, false);
- filesize = tmpsize;
- cremsg();
- }
-
- /*
- * F command: copy a message to a file.
- */
-
- filmsg()
- {
- register char *p;
- register short hdr, append, inhdr;
- register FILE *out;
-
- if (!findmsg(atoi(port->fld[1]))) { port->msg = mnmsg; return; }
-
- hdr = true;
- append = false;
- inhdr = false;
-
- if (port->flds is 4) for (p = port->fld[3]; *p; p++) switch (*p)
- {
- case 'A' : append = true; break;
- case 'N' : hdr = false; break;
- case 'I' : inhdr = true; break;
- default: ;
- }
-
- if (port->opt2 is ' ') strcpy(port->line, port->fld[2]);
- else if (getdir(port->fld[2]) is NULL) { port->msg = mndir; return; }
-
- if (append) out = fopen (port->line, "a"); else
- {
- if ((out = fopen (port->line, "r")) isnt NULL)
- { fclose(out); port->msg = mexst; return; }
- out = fopen (port->line, "w");
- }
-
- if (out is NULL) { port->msg = mcant; return; }
-
- sprintf(tmp->scr, "%s %s", port->fld[1], port->line);
- log('M', 'D', port->opt2, tmp->scr);
-
- prthdr(true, true);
-
- if (hdr) fputs(tmp->scr, out);
-
- msgfile(port->cmd, port->mmhs->number);
-
- if ((port->fl = fopen(port->cmd, "r")) is NULL)
- { fclose(out); nofile(port->cmd); return; }
- fseek( port->fl, (long)RECSIZE, 0);
- while (fgets(tmp->scr, linelen, port->fl) isnt NULL)
- {
- if (!inhdr)
- {
- if (!parsehd(tmp->scr)) fputs(tmp->scr, out);
- }
- else
- fputs(tmp->scr, out);
- }
- fclose(port->fl);
- fclose(out);
- }
-
- /*
- * Upload the message text file.
- */
-
- uloadm(tname)
- char *tname;
- {
- register char *tp;
- register PORTS *p;
- short first, head;
- char *a, *b;
- #ifdef MCH_AMIGA
- register int i;
- char orgcall[7];
- #endif
- orgbbs[0] = '\0';
-
- p = port;
- if ((p->fl = fopen(tname, "w")) is NULL) { p->msg = mcant; return false; }
- fill(tmp->scr, '.', RECSIZE);
- tmp->scr[256] = '\0';
- fputs( tmp->scr, p->fl);
-
- first = true;
- head = true;
- filesize = 0;
- while (true)
- {
- while(!getdat());
-
- /*
- * If user disconnected, timed out, or forced off, zap the file.
- */
-
- if (p->mode & gone)
- {
- fclose(p->fl);
- return false;
- }
-
- if (head)
- {
- if (!parsehd(p->line)) head = false;
- else
-
- /* If this is a ping-pong message */
- if (s_param & s_ping)
- {
- a = p->cmd;
- b = cport->user->call;
- unbl(a, b, 6);
- if (matchn(orgbbs, p->cmd, ln_call))
- {
- holdit = true;
- port->mmhs->htype = 'P';
- }
- }
- #ifdef MCH_AMIGA
- /* Check each R: line in the bulletin header. If the BBS call is in our
- distribution list for this bulletin, then mark them as already having
- received the bulletin.
- */
- if(head && p->mmhs->ext == 1) {
- pcall(orgcall,orgbbs);
- for(i = 0;i < p->mmhs->count; i++) {
- if(p->mmhs->flag[i]) {
- if(matchn(orgcall,p->mmhs->call[i],ln_call)) {
- p->mmhs->flag[i] = false;
- break;
- }
- }
- }
- }
- #endif
- }
- /*
- * If the first line is not a header (thus it is a human entering
- * the message), make sure there is an initial blank line before
- * the body of the message.
- */
-
- if (first)
- {
- first = false;
- if (*orgbbs is '\0') if (*p->line isnt '\n') fputs("\n", p->fl);
- }
-
- /*
- * Stuff the line into the file.
- */
-
- if (match(p->line, "/EX\n") or match(p->line,"/ex\n"))
- {
- fclose(p->fl);
- return true;
- }
-
-
- if ((tp = strchr(p->line, cpmeof)) is NULL)
- {
- filesize += strlen(p->line);
- fputs(p->line, p->fl);
- }
- else
- {
- if (tp isnt p->line)
- {
- *tp++ = '\n';
- *tp = '\0';
- filesize += strlen(p->line);
- fputs(p->line, p->fl);
- }
- fclose(p->fl);
- return true;
- }
- }
- }
-
- /*
- * "Display the message text" utility.
- */
-
- dloadm(sh)
- short sh;
- {
- short first;
-
- sprintf(port->line, "%u", port->mmhs->number);
- log('M', 'R', port->opt2, port->line);
- port->mmhs->read++;
- if (matchn(port->user->call, port->mmhs->to, ln_call))
- port->mmhs->stat setbit m_read;
- if (port->mmhs->ext is 1)
- if (matchn(port->user->call, port->mmhs->call[0], ln_call))
- {
- markdis(0);
- port->mmhs->stat clrbit m_hold;
- }
- wt_mmhs();
- makehdr2();
- prthdr(true, true);
-
- msgfile(port->line, port->mmhs->number);
-
- if ((port->fl = fopen(port->line, "r")) is NULL)
- { nofile(port->line); return; }
-
- #ifdef MCH_AMIGA
-
- /* Code to save the information that will allow the Send Reply command
- to construct a proper reply to this message. At the moment a reply
- is permitted only for personal messages addressed to the reader.
- (I'm not sure that this test is needed, but play it safe).
- REMOVED until I have the SR command working properly.
- */
- #ifdef MCH_SR
- if(port->mmhs->type == 'P') {
- /* matchn(port->user->call,port->mmhs->to,ln_call)) { */
- last_msg.type = 'P';
- unbl(last_msg.from,port->mmhs->from,ln_call);
- unbl(last_msg.bbs,port->mmhs->bbs,ln_call);
- strncpy(last_msg.title,port->mmhs->title,mhtitl);
- }
- else last_msg.type = 0;
- #else
- last_msg.type = 0;
- #endif
-
- /* Start the line counter */
- pgst(NULL);
- #endif
-
- fseek( port->fl, (long)RECSIZE, 0 );
- pgck(); /* First line of header */
- pgck(); /* Second line of header */
- pgck(); /* Path line */
- if (port->mmhs->ext) pgck();
- if (*port->mmhs->bid isnt ' ') pgck();
-
- strcpy(tmp->scr, " Path: ");
- first = true;
-
- #ifdef MCH_AMIGA
- interflag = 0;
- #endif
-
- while(fgets(port->line, linelen, port->fl) isnt NULL)
- {
-
- #ifdef MCH_AMIGA
- if(interflag && (port != cport)) {
- break;
- }
- #endif
-
- if (!sh)
- {
- sh = !parsehd(port->line);
- if (sh)
- {
- if (!first)
- {
- strcat(tmp->scr, "\n\n");
- outstr(tmp->scr);
- pgck();
- prtx("Date: $j/$k\n"); pgck();
- prtx("From: $P @ $a\n"); pgck();
- prtx("Message-Id: <$m@$a>\n"); pgck();
- prtx("To: $G @ ");
- if (*port->mmhs->bbs is ' ') prtx("$O\n");
- else if (port->mmhs->ext is 2) prtx("$h\n");
- else prtx("$A\n"); pgck();
- prtx("Subject: $E\n\n"); pgck();
- }
- }
- else
- {
- if (!first) strcat(tmp->scr, "!");
- strcat(tmp->scr, orgbbs);
- first = false;
- }
- }
-
- if (sh)
- {
- outstr(port->line);
- if (lstquit()) { fclose(port->fl); return; }
- }
- }
- fclose (port->fl);
- }
-
- /*
- * RM command: read my messages.
- */
-
- rdmsgm()
- {
- register short found;
- register word h;
-
- found = false;
- #ifdef MCH_AMIGA
- check_mail();
- unlock_mail();
- #endif
- for (h = mfhs->first; h and h <= mfhs->last; h++)
- {
- read_rec(mfl, h, (char *)port->mmhs);
- if ((!(port->mmhs->stat & (m_read|m_kill|m_fwd|m_hold|m_busy)) and
- (matchn(port->user->call, port->mmhs->to, ln_call))) or
- (!(port->mmhs->stat & (m_read|m_kill|m_fwd|m_busy)) and
- (port->mmhs->ext is 1) and
- matchn(port->user->call, port->mmhs->call[0], ln_call) and
- port->mmhs->flag[0]))
- {
- dloadm(port->mode & ops);
- found = true;
- if (pause() is 'Q') return;
- }
- }
- if (!found) port->msg = mfind;
- }
-
- /*
- * R command: read one message.
- */
-
- rdmsg()
- {
- char sn[6];
- if ((strlen(port->fld[1]) > 5) or (!num(port->fld[1])))
- {
- port->msg = mwhat;
- return;
- }
- strcpy(sn, port->fld[1]);
- if (!findmsg(atoi(port->fld[1]))) { port->msg = mnmsg; return; }
- if (!rpermit()) { port->msg = mprot; return; }
-
- dloadm(port->opt2 is 'H');
- if ((port->mmhs->type is 'T')and(!(port->mmhs->stat&(m_busy|m_kill|m_fwd))))
- {
- outstr("\nAre you going to deliver this message (Y/N)?\n");
- while (!getdat());
- if(toupper(*port->line) is 'Y')
- {
- port->opt2 = 'T';
- strcpy(port->fld[1], sn);
- sprintf(port->line, "KT %s\n", sn);
- outstr(port->line);
- klmsg();
- }
- }
- }
-
- /*
- * KF, KM, KO, KY, KK commands, kill multiple messages.
- */
-
- klmsgm()
- {
- register short ok;
- register short found;
- word h, next;
- if (port->flds is 2) pcall(tcall, port->fld[1]);
-
- #ifdef MCH_AMIGA
- check_mail();
- unlock_mail();
- #endif
- found = false;
- for (h = mfhs->first; h and h <= mfhs->last; h++)
- {
- read_rec(mfl, h, (char *)port->mmhs);
-
- ok = kpermit();
- if (ok) ok = !(port->mmhs->stat & m_hold);
-
- if (ok) if (port->flds is 2) ok = matchn(tcall, port->mmhs->to, ln_call);
-
- if (ok) switch(port->opt2)
- {
- case 'F' : ok = (port->mmhs->stat & m_fwd); break;
- case 'M' :
- ok = ((port->mmhs->stat & m_read) and
- matchn(port->user->call, port->mmhs->to, ln_call));
- break;
- case 'O' : ok = (port->mmhs->stat & m_stale); break;
- case 'Y' : ok = (port->mmhs->stat & m_read); break;
- }
-
- if (ok)
- {
- sprintf(port->line, "%u", port->mmhs->number);
- log('M', 'K', port->opt2, port->line);
- prtx(mm[7]);
- found = true;
- port->mmhs->stat setbit m_kill;
- write_rec(mfl, port->mmhs->rn, (char *)port->mmhs);
- makehdr2();
- }
- }
- #ifdef MCH_AMIGA
- titles();
- #endif
- if (!found) port->msg = mfind;
- }
-
- klmult()
- {
- mult(false);
- }
-
- rdmult()
- {
- mult(true);
- }
-
- /*
- * Handling multiple messages.
- */
-
- mult(x)
- int x;
- {
- static char msgn[25];
- int i;
-
- strncpy(&msgn[0], port->fld[2], 5);
- strncpy(&msgn[6], port->fld[3], 5);
- strncpy(&msgn[12], port->fld[4], 5);
- strncpy(&msgn[18], port->fld[5], 5);
- if (x) rdmsg();
- else
- {
- outstr(port->fld[1]);
- klmsg();
- }
- prtx(port->msg);
- for ( i=0; msgn[i]; i += 6)
- {
- strcpy(port->fld[1], &msgn[i]);
- if (x) rdmsg();
- else
- {
- outstr(port->fld[1]);
- klmsg();
- }
- prtx(port->msg);
- port->msg = NULL;
- }
- }
-
- /*
- * K command, kill a message.
- */
-
- klmsg()
- {
- register short dosvc;
- unsigned int org_num;
-
- if (!num(port->fld[1])) { port->msg = mwhat; return; }
- if (!findmsg(atoi(port->fld[1]))) { port->msg = mnmsg; return; }
- if (port->mmhs->stat & m_kill) { port->msg = mnmsg; return; }
- if (!kpermit()) { port->msg = mprot; return; }
-
- log('M', 'K', port->opt2, port->fld[1]);
-
- dosvc = (port->opt2 is 'T') and
- (port->mmhs->type is 'T') and
- (s_param & s_svc);
-
- if (dosvc) org_num = atoi(port->fld[1]);
-
- /*
- * Marked the message as Killed.
- */
-
- if(port->opt2 is 'A') port->mmhs->stat setbit m_noarc;
- port->mmhs->stat setbit m_kill;
- write_rec(mfl, port->mmhs->rn, (char *)port->mmhs);
- makehdr2();
-
- /*
- * If this is KT of T type message, and we do service messages,
- * do the service message.
- */
-
- if (dosvc)
- {
- port->mmhs->ext = 0;
- findat();
- port->opt1 = 'S';
- strncpy(port->mmhs->to, port->mmhs->from, ln_call);
- strncpy(port->mmhs->from, cport->user->call, ln_call);
- port->mmhs->type = 'P';
- fill(port->mmhs->bid, ' ', ln_bid);
- initmsg(false);
- msgfile(port->line, mfhs->next_msg);
- port->fl = fopen(port->line, "w");
- fseek(port->fl, (long)RECSIZE, 0);
- fprintf(port->fl, "Msg %5u taken from %6.6s by %6.6s at %4.4s on %6.6s\n",
- org_num, cport->user->call, port->user->call, l_time, l_date);
- fclose(port->fl);
-
- filesize = 56;
- cremsg();
- }
- port->msg = mdone;
- #ifdef MCH_AMIGA
- titles();
- #endif
- }
-
- /*
- * S command: send a message.
- */
-
- sndmsg()
- {
- char *a, *b;
-
- holdit = false; /* initialize it to something */
- #ifndef MCH_AMIGA
- pfld();
- #else
- if(srcmd_flag == 0)last_msg.type = 0;
- /* If there's an error in the command then return */
- if(pfld() == 0)return;
-
- /* Initialize ->ext to zero so that dodis() will detect that sndmsg has
- already done it and then cremsg won't redo it. This is so that the
- uloadm routine can use parsehd() to see if an incoming bulletin has
- already been seen by other BBS in the distribution list and then we
- won't have to send it to them.
- The only other call to dodis() previously sets ->ext to zero.
- */
- if(port->mmhs->ext != 2)port->mmhs->ext = 0;
- dodis();
- #endif
-
- if (!isalnum(*port->mmhs->to))
- {
- holdit = true;
- port->mmhs->htype = 'C';
- }
- if (port->mode & gone) return;
-
- if (s_mart) {
- if (!needbid) return;
- }
- else {
- if (port->user->options & (u_bbs | u_expert))
- outstr("Msg:\n");
- else prtx(mm[1]);
- }
-
- msgfile(port->cmd, mfhs->next_msg);
- if (!uloadm(port->cmd)) return;
-
- /*
- * If this is a Bulletin and has no BID,
- * parse the headers and give it one.
- */
- #ifndef MCH_AMIGA
- if (!iscall(port->mmhs->to))
- if (port->mmhs->type is 'B')
- {
- #else
- /* Add BID or a MID to any kind of message */
- if(*port->mmhs->bid == ' ') {
- unbl(port->line, cport->user->call, ln_call);
- #endif
- a = port->line;
- b = cport->user->call;
- unbl(a, b, 6);
-
- /* Default the BID as to coming from this BBS with our msg number. */
-
- sprintf(tmp->scr, "%-u_%-s", mfhs->next_msg, port->line);
-
- /* Now check the parsed headers if it came from another BBS. */
-
- if (*orgbbs isnt '\0') sprintf(tmp->scr, "%s_%s", orgmsg, orgbbs);
-
- if (!hasbid)
- {
- strncpy(port->mmhs->bid, tmp->scr, ln_bid);
- hasbid = true;
- }
- else if (!matchn(port->mmhs->bid, tmp->scr, ln_bid)) putbid(false);
-
- if (port->user->options & u_hold)
- {
- holdit = true;
- port->mmhs->htype = 'U';
- }
- }
- checkbid();
- if (!needbid)
- {
- holdit = true;
- port->mmhs->htype = 'D';
- }
- cremsg();
- }
-
- /*
- * SM command, send a message to a distribution list.
- */
-
- sndmlt()
- {
- register FILE *fl;
- char fn[80];
- register short first = true;
- word tmpsize;
-
- holdit = false;
- fill(port->mmhs->bid, ' ', ln_bid);
-
- if ((fl = fopen(port->fld[1], "r")) is NULL)
- { nofile(port->fld[1]); return; }
-
- prtx(mm[0]);
- get_title();
- if (port->mode & gone) { fclose(fl); return; }
-
- if (port->flds is 3) if (*port->fld[port->flds-1] is '$')
- {
- /* MCH_AMIGA */
- if (*(port->fld[port->flds-1] + 1) /*isnt NULL*/)
- {
- strncpy(port->mmhs->bid, port->fld[port->flds-1] + 1, ln_bid);
- hasbid = true;
- }
- }
-
- prtx(mm[1]);
-
- strncpy(port->mmhs->from, port->user->call, ln_call);
- port->mmhs->ext = 0;
- initmsg(false);
- msgfile(fn, mfhs->next_msg);
- if (!uloadm(fn)) { fclose(fl); return; }
- tmpsize = filesize;
-
- while (fgets(port->line, linelen, fl) isnt NULL)
- {
- parse();
- if (!first)
- {
- port->mmhs->ext = 0;
- initmsg(false);
- msgfile(port->line, mfhs->next_msg);
- copy(fn, port->line, false);
- }
- port->mmhs->type = port->opt2;
- pcall(port->mmhs->to, port->fld[1]);
- fill(port->mmhs->bbs, ' ', ln_call);
-
- if(port->flds > 3) atfrom(2);
- if(port->flds > 5) atfrom(4);
- filesize = tmpsize;
- #ifdef MCH_AMIGA
- replace_bbs();
- /* Put a BID or MID on this file if needed */
- if( (port->mmhs->type is 'B') || (port->mmhs->type == 'P')) {
- unbl(port->line, cport->user->call, ln_call);
-
- /* Default the BID as to coming from this BBS with our msg number. */
-
- sprintf(tmp->scr, "%-u_%-s", mfhs->next_msg, port->line);
- strncpy(port->mmhs->bid, tmp->scr, ln_bid);
- hasbid = true;
- }
- #endif
- cremsg();
- first = false;
- }
- fclose(fl);
- }
-
- /*
- * M command, make a message from a file.
- */
-
- makmsg()
- {
- #ifdef MCH_AMIGA
- char *a,*b;
- #endif
- if ((port->fl = fopen(port->fld[2], "r")) is NULL)
- { nofile(port->fld[2]); return; }
- fclose(port->fl);
- #ifndef MCH_AMIGA
- pfld();
- #else
- /* If there's an error in the command then return */
- if(pfld() == 0)return;
- #endif
- if (port->mode & gone) return;
- #ifdef MCH_AMIGA
- /* Put a BID or MID on this file if needed */
- if( (port->mmhs->type is 'B') || (port->mmhs->type == 'P')) {
- unbl(port->line, cport->user->call, ln_call);
-
- /* Default the BID as coming from this BBS with our msg number. */
-
- sprintf(tmp->scr, "%-u_%-s", mfhs->next_msg, port->line);
- strncpy(port->mmhs->bid, tmp->scr, ln_bid);
- hasbid = true;
- }
- #endif
- msgfile(port->line, mfhs->next_msg);
- copy(port->fld[2], port->line, true);
- cremsg();
- }
-
- /*
- * MM command, make multiple messages from a file.
- */
-
- makmlt()
- {
- register FILE *dfl;
- char tnm[80];
-
- holdit = false;
- fill(port->mmhs->bid, ' ', ln_bid);
-
- if ((port->fl = fopen(port->fld[2], "r")) is NULL)
- { nofile(port->fld[2]); return; }
- fclose(port->fl);
-
- if ((dfl = fopen(port->fld[1], "r")) is NULL)
- { nofile(port->fld[1]); return; }
-
- strcpy(tnm, port->fld[2]);
-
- if (port->flds is 4) if (*port->fld[port->flds-1] is '$')
- {
- /* MCH_AMIGA */
- if (*(port->fld[port->flds - 1] + 1)/* isnt NULL*/)
- {
- strncpy(port->mmhs->bid, port->fld[port->flds-1] + 1, ln_bid);
- hasbid = true;
- }
- }
-
- prtx(mm[0]);
- get_title();
- if (port->mode & gone) { fclose(dfl); return; }
-
- while (fgets(port->line, linelen, dfl) isnt NULL)
- {
- parse();
- port->mmhs->type = port->opt2;
- pcall(port->mmhs->to, port->fld[1]);
- strncpy(port->mmhs->from, port->user->call, ln_call);
- fill(port->mmhs->bbs, ' ', ln_call);
- port->mmhs->ext = 0;
-
- if (port->flds > 3) atfrom(2);
- if (port->flds > 5) atfrom(4);
- #ifdef MCH_AMIGA
- /* Put a BID or MID on this file if needed */
- if( (port->mmhs->type is 'B') || (port->mmhs->type == 'P')) {
- unbl(port->line, cport->user->call, ln_call);
-
- /* Default the BID as to coming from this BBS with our msg number. */
-
- sprintf(tmp->scr, "%-u_%-s", mfhs->next_msg, port->line);
- strncpy(port->mmhs->bid, tmp->scr, ln_bid);
- hasbid = true;
- }
- replace_bbs();
- #endif
- initmsg(false);
- msgfile(port->line, mfhs->next_msg);
- copy(tnm, port->line, true);
- cremsg();
- }
- fclose(dfl);
- }
-
- /*
- * Mark stale messages.
- */
-
- stale()
- {
- register word i;
- register int ks;
- register short ts;
-
- for (i = mfhs->first; i and i <= mfhs->last; i++)
- {
- read_rec(mfl, i, (char *)port->mmhs);
-
- switch(port->mmhs->type)
- {
- case 'T': ts = tstalen; ks = (s_flag & s_nkill); break;
- case 'P': ts = tstaleu; ks = (s_flag & s_ukill); break;
- default :
- {
- ts = tstaleb; ks = (s_flag & s_bkill); /* Max time period */
- #ifdef MCH_AMIGA
- /* If this is a bulletin and the lifetime is less than the default
- then use the lifetime
- */
- if(port->mmhs->type is 'B') {
- if(port->mmhs->lifetime && (port->mmhs->lifetime < ts)) {
- ts = port->mmhs->lifetime;
- }
- }
- #endif
- if (!(port->mmhs->stat & m_bull))
- {
- if (ddiff(port->mmhs->date, l_date, true) > tstale1) /* 1st time period */
- if (port->mmhs->read < rstale1) ts = 0;
- if (ddiff(port->mmhs->date, l_date, true) > tstale2) /* 2nd time period */
- if (port->mmhs->read < rstale2) ts = 0;
- if (ddiff(port->mmhs->date, l_date, true) > tstale3) /* 3rd time period */
- if (port->mmhs->read < rstale3) ts = 0;
- }
- }
- }
-
- if (!(port->mmhs->stat & m_stale))
- if (ddiff(port->mmhs->date, l_date, true) > ts)
- {
- if (ks and !(port->mmhs->stat & m_hold)) port->mmhs->stat setbit m_kill;
- else port->mmhs->stat setbit m_stale;
- write_rec(mfl, i, (char *)port->mmhs);
- }
- }
- }
-
- /*
- * DW command: make wp message from user file.
- */
-
- dwuser()
- {
- register int i;
- register short first = true;
- short doall;
-
- if (*wpcall is ' ') return;
-
- doall = port->flds is 2;
- port->opt1 = 'S';
- port->opt2 = 'P';
- filesize = 0;
- #ifdef MCH_AMIGA
- check_user();
- unlock_user();
- #endif
-
- for (i = 1; i <= ufhs->count; i++)
- {
- read_rec(ufl, i, (char *)tuser);
- if ((tuser->state & u_home) and (tuser->state & u_zip))
- if (doall or !(tuser->state & u_sent))
- {
- if (first)
- {
- first = false;
- port->mmhs->type = 'P';
- strncpy(port->mmhs->to, "WP ", ln_call);
- strncpy(port->mmhs->from, cport->user->call, ln_call);
- strncpy(port->mmhs->bbs, wpcall, ln_call);
- strcpy(port->mmhs->title, "WP Update");
- fill(port->mmhs->bid, ' ', ln_bid);
- port->mmhs->ext = 0;
- initmsg(false);
- msgfile(port->line, mfhs->next_msg);
- port->fl = fopen(port->line, "w");
- fseek(port->fl, (long)RECSIZE, 0);
- }
-
- filesize += 72;
- fprintf(port->fl, "On %6.6s %6.6s @ %6.6s zip %6.6s %-12.12s %-20.20s\n",
- tuser->date, tuser->call, tuser->home_bbs, tuser->zip,
- tuser->handle, tuser->qth);
-
- tuser->state setbit u_sent;
- if (s_flag & s_dv) begin_lock();
- write_rec(ufl, i, (char *)tuser);
- if (s_flag & s_dv)end_lock();
- if (i is port->user->rn) port->user->state setbit u_sent;
- }
- }
-
- if (!first)
- {
- fclose(port->fl);
- chkhier();
- cremsg();
- }
- }
-
- /*
- * E command, edit a message header.
- */
-
- edmsg()
- {
- FILE *out;
- char *a, *b;
- #ifdef MCH_AMIGA
- short life;
- #endif
-
- if (!findmsg(atoi(port->fld[1]))) { port->msg = mnmsg; return; }
- while (*port->fld[0] isnt '\0')
- {
- prthdr(true, true);
- #ifdef MCH_AMIGA
- if(port->mmhs->type == 'B')
- outstr("t(Y)pe, (S)tatus, (T)o, (F)rom, (B)bs, t(I)tle, bi(D), (L)ifetime\n");
- else
- #endif
- outstr("t(Y)pe, (S)tatus, (T)o, (F)rom, (B)bs, t(I)tle, bi(D)\n");
- getcmd();
- if (port->mode & gone) return;
- switch (*port->fld[0])
- {
- #ifdef MCH_AMIGA
- case 'L' :
- if(port->mmhs->type == 'B') {
- life = atoi(port->fld[1]);
- if((life >= 0) && (life < 256))port->mmhs->lifetime = life;
- }
- /* This 'L' command confuses prthdr(). So unconfuse it */
- port->opt1 = ' ';
- break;
- #endif
- case 'T' : pcall(port->mmhs->to, port->fld[1]); break;
- case 'F' : pcall(port->mmhs->from, port->fld[1]); break;
- case 'B' : edbbs(1); break;
- case 'I' : if (*port->fld[1])
- {
- remnl(port->line);
- strncpy(port->mmhs->title, port->line+2, mhtitl);
- }
- else *port->mmhs->title = '\0';
- break;
- case 'S' : switch(*port->fld[1])
- {
- case 'F' : port->mmhs->stat = m_fwd; break;
- case 'H' : port->mmhs->stat = m_hold; break;
- case 'N' : port->mmhs->stat = 0; break;
- case 'O' : port->mmhs->stat = m_stale; break;
- case 'Y' : port->mmhs->stat = m_read; break;
- case '$' : port->mmhs->stat setbit m_bull; break;
- }
- break;
- case 'Y' : if(*port->fld[1]) port->mmhs->type = *port->fld[1];
- else port->mmhs->type = ' '; break;
-
- case 'D' : if(*port->fld[1]) strncpy(port->mmhs->bid, port->fld[1], ln_bid);
- else fill(port->mmhs->bid, ' ', ln_bid);
- break;
- }
- }
- wt_mmhs();
- makehdr2();
- if (*port->mmhs->bid isnt ' ')
- {
- checkbid();
- if (needbid)
- {
- #ifdef MCH_AMIGA
- lock_bid();
- #endif
- if ((out = fopen(bidfile,"a")) is NULL)
- {
- #ifdef MCH_AMIGA
- unlock_bid();
- #endif
- port->msg = mcant; return;
- }
-
- a = port->cmd;
- b = port->mmhs->bid;
- unbl(a, b, ln_bid);
-
- sprintf(port->line, "%4.4s%s\n", port->mmhs->date + 2, port->cmd);
- if (s_flag & s_dv) begin_lock();
- fputs(port->line, out);
- if (s_flag & s_dv) end_lock();
- fclose(out);
- #ifdef MCH_AMIGA
- unlock_bid();
- #endif
- }
- }
- }
-
- /*
- * ET command, edit an NTS traffic message header.
- */
-
- edtfc()
- {
- register short ok;
-
- if (!findmsg(atoi(port->fld[1]))) { port->msg = mnmsg; return; }
- prthdr(true, true);
-
- ok = (port->mmhs->type is 'T');
- if (!ok) ok = ((port->mmhs->type is ' ') and matchn(port->mmhs->to, "NTS", 3));
- if (!ok) { port->msg = mm[12]; return; }
-
- prtx(mm[8]);
- getcmd();
- if (port->mode & gone) return;
- if (port->flds) pcall(port->mmhs->to, port->fld[0]);
-
- prtx(mm[9]);
- getcmd();
- if (port->mode & gone) return;
- edbbs(0);
-
- prtx(mm[10]);
- getcmd();
- if (port->mode & gone) return;
- if (port->flds)
- {
- remnl(port->line);
- strncpy(port->mmhs->title, port->line, mhtitl);
- }
- else if (*port->line is ' ') *port->mmhs->title = '\0';
-
- prtx(mm[11]);
- getcmd();
- if (port->mode & gone) return;
- if (port->flds) port->mmhs->type = *port->fld[0];
- else if (*port->line is ' ') port->mmhs->type = ' ';
-
- port->mmhs->stat = 0;
- prthdr(true, true);
- wt_mmhs();
- makehdr2();
- sprintf(port->line, "%u %-.6s %s",
- port->mmhs->number, port->mmhs->to, port->mmhs->title);
- log('M', 'E', port->opt2, port->line);
- }
-
- edbbs(f)
- int f;
- {
- fill(port->mmhs->call, '\0', 92);
- port->mmhs->ext = 0;
- fill(port->mmhs->bbs, ' ', ln_call);
- if(*port->fld[f])
- {
- pcall(port->mmhs->bbs, port->fld[f]);
- if (strchr(port->fld[f], '.') is NULL) dodis();
- else
- {
- port->mmhs->ext = 2;
- strncpy(port->mmhs->call[0], port->fld[f], ln_hier);
- }
- if (port->mmhs->ext is 0) chkhier();
- }
- }
-
- /*
- * Check to see if bbs has match in STATES.MB file and add state code
- * to hierarchical call.
- */
-
- chkhier()
- {
- FILE *hier;
- char hiercall[ln_call], bbs[ln_call+1], phier[ln_hier];
- char *p;
- #ifdef MCH_AMIGA
- register char *q;
- #endif
-
- if (*port->mmhs->bbs is ' ') return;
- if(( hier = fopen( stfile, "r")) is NULL) return;
- while( fgets( tmp->scr, linelen, hier) isnt NULL)
- {
- pcall(hiercall, tmp->scr);
- if( wcm(hiercall, port->mmhs->bbs))
- {
- #ifndef MCH_AMIGA
- remnl(tmp->scr);
- #endif
- p = strchr(tmp->scr, '.');
- unbl(bbs, port->mmhs->bbs, ln_call);
- unbl(phier, p, ln_hier);
- #ifdef MCH_AMIGA
- /* If the hierarchical portion has .USA or .CAN on the end then add .NA */
- for(q=phier;*q;q++);
- p = q;
- while((q > phier) && (*q != '.'))q--;
- if(matchn(".USA",q,4) || matchn(".CAN",q,4)) {
- strcpy(p,".NA");
- }
- #endif
- port->mmhs->ext = 2;
- fill( port->mmhs->call[0], '\0', 92);
- sprintf( port->mmhs->call[0], "%s%s", bbs, phier);
- fclose(hier);
- return;
- }
- }
- fclose(hier);
- return;
- }
-
- /*
- * Compress the bidfile by removing old bids
- */
-
- cprs_bid()
- {
- FILE *bfl, *bbfl;
- int x, yy, zz;
- char biddate[7];
-
- unlink(bbidfile);
- rename(bidfile, bbidfile);
- unlink(bidfile);
-
- if ((bfl = fopen(bidfile, "a")) is NULL)
- {
- #ifndef MCH_AMIGA
- printf("Error opening %s\n", bidfile);
- #else
- sprintf(tmpstr,"Error opening %s\n", bidfile);
- ttputs(tmpstr);
- #endif
- return;
- }
- if ((bbfl = fopen(bbidfile, "r")) is NULL)
- {
- nofile(bbidfile);
- return;
- }
-
- yy=0; zz=0;
- #ifndef MCH_AMIGA
- printf("Compressing bid file.......\n");
- #else
- /* NOTE that this routine is called at the same time as a GM is done and
- there is already a lock on the whole system when this function executes
- so there's no need to lock the BID semaphore.
- */
- ttputs("Compressing bid file.......\n");
- #endif
- while (fgets(port->line, linelen, bbfl) isnt NULL)
- {
- fill (biddate, ' ', 6);
- strncpy (biddate + 2, port->line, 4);
- yy++;
- if ((x = ddiff(biddate, l_date, false)) < 0)
- x += 365;
- if (x < bidnum)
- {
- fputs (port->line, bfl);
- zz++;
- }
- }
- #ifndef MCH_AMIGA
- printf("There were %d records, now %d remain\n",yy,zz);
- printf("Compression completed\n");
- #else
- sprintf(tmpstr,"There were %d records, now %d remain\n",yy,zz);
- ttputs(tmpstr);
- ttputs("Compression completed\n");
- /* Get the BID semaphore and set the new length of file */
- #endif
-
- fclose (bfl);
- fclose (bbfl);
- }
-
- #ifdef MCH_AMIGA
- check_mail()
- {
- extern long get_mail();
- lock_mail();
- if(mfhs->count != get_mail()) {
- close(mfl);
- mfl = open(mbfile, O_RDWR | O_BINARY);
- read_rec(mfl, 0, (char *)mfhs);
- titles();
- }
- }
- #endif
-